
struct TreeNode {
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode() : val(0), left(nullptr), right(nullptr) {}
    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
    TreeNode(int x, TreeNode* left, TreeNode* right) : val(x), left(left), right(right) {}
    
};

bool evaluateTree(TreeNode* root) {
    if (root->left == nullptr)
        return root->val;

    bool left = evaluateTree(root->left);
    bool right = evaluateTree(root->right);
    if (root->val == 2)
        root->val = left | right;
    else
        root->val = left & right;

    return root->val;
}

int dfs(TreeNode* root, int presum)
{
    if (root == nullptr)
        return 0;

    int sum = presum * 10 + root->val;
    if (root->left == nullptr && root->right == nullptr)
        return sum;

    int left = dfs(root->left, sum);
    int right = dfs(root->right, sum);

    return left + right;
}

int sumNumbers(TreeNode* root) {
    return dfs(root, 0);
}

int main()
{
    TreeNode* root = new TreeNode(2);
    TreeNode* lchild = new TreeNode(1);
    TreeNode* rchild = new TreeNode(0);
    root->left = lchild;
    root->right = rchild;

    evaluateTree(root);
    sumNumbers(root);

    return 0;
}